package net.lab0.fractal.fractals;


import net.lab0.fractal.classes.ViewCoordinates;


/**
 * @author 116
 */
public class MandelbrotRunnable
implements Runnable
{
	private Mandelbrot	parent;
	private int			width;
	private int			height;
	private int			lineNumber;
	private int[]		pixels;
	private boolean		finished;
	
	public MandelbrotRunnable(Mandelbrot parent, int width, int height, int lineNumber)
	{
		this.parent = parent;
		this.width = width;
		this.height = height;
		this.finished = false;
		if (height > lineNumber)
		{
			this.lineNumber = lineNumber;
		}
		else
		{
			lineNumber = 0;
		}
	}
	
	public int[] renderLine()
	{
		ViewCoordinates c = parent.getCoordinates();
		pixels = new int[width];
		double xStep = c.getWidth() / width;
		double yStep = c.getHeight() / height;
		int maxIterations = parent.getMaxIterations();
		for (int x = 0; x < width; x++)
		{
			int y = lineNumber;
			int iter = 0;
			double x0, x1, y0, y1;
			x0 = x1 = c.getxCenter() - c.getWidth() / 2 + xStep * x;
			y0 = y1 = c.getyCenter() - c.getHeight() / 2 + yStep * y;
			// cardiod + 1st bulb test, cf wiki
			double q = (x0 - 0.25) * (x0 - 0.25) + y0 * y0;
			boolean inside = (q * (q + (x0 - 0.25)) < y0 * y0 * 0.25) || (((x0 + 1) * (x0 + 1) + y0 * y0) < 0.0625);
			if (!inside)
			{
				while (x1 * x1 + y1 * y1 <= 4 && iter < maxIterations)
				{
					double tempX = x1 * x1 - y1 * y1 + x0;
					y1 = 2 * x1 * y1 + y0;
					x1 = tempX;
					iter++;
				}
			}
			else
			{
				iter = maxIterations;
			}
			pixels[x] = iter;
		}
		finished = true;
		return pixels;
	}
	
	@Override
	public void run()
	{
		finished = false;
		renderLine();
	}
	
	public int[] getPixels()
	{
		return pixels;
	}
	
	public boolean isFinished()
	{
		return finished;
	}
}
